﻿using Shinva.LADModel.Abstractions;
using Shinva.Variables.Interface;
using Shinva.Variables.Models;
using Shinva.Variables.Type.bit;
using Shinva.Variables.Type.floating;
using Shinva.Variables.Type.integer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Shinva.LADModel.Type.ComparatorOperations
{
    public enum RangeType
    {
        InRange,
        OutRange,
    }
    public class Range<T> : ElementNodeBase where T : PlcMemberBase
    {
        public T min { get; set; }
        public T val { get; set; } //实际是in
        public T max { get; set; }
        private readonly RangeType _rangeType;
        public override PlcBool EN
        {
            get
            {
                return en;
            }
            set
            {
                en = value;
            }
        }
        public override PlcBool ENO
        {
            get
            {

                eno.Value = en.Value && Compare();
                return eno;
            }
            set
            {
                eno = value;
            }
        }

        public Range(RangeType rangeType)
        {
            Name = "Range";
            _rangeType = rangeType;
            variableTableInterface.AddVariable("min", StorageType.Input);
            variableTableInterface.AddVariable("val", StorageType.Input);
            variableTableInterface.AddVariable("max", StorageType.Input);

            min =variableTableInterface.GetVariableValue<T>("min");
            val = variableTableInterface.GetVariableValue<T>("val");
            max= variableTableInterface.GetVariableValue<T>("max");
        }
        public override IPlcMember GetInterfaceVariableByName(string name)
        {
            if (name == "pre") return EN;
            else if (name == "out") return ENO;
            else if (name == "in") return val;
            else return variableTableInterface.GetVariableValue<IPlcMember>(name);
        }
        //参考一下add中的计算逻辑修改一下
        public bool Compare()
        {
            if (min == null || val == null || max == null) return false;
            if (min is PlcInt || min is PlcSInt || min is PlcUInt || min is PlcUDInt || min is PlcReal || min is PlcLReal)
            {
                int comparisonResult = min.Value.CompareTo(val.Value);
                int comparisonResult2 = val.Value.CompareTo(max.Value);
                return _rangeType switch
                {
                    RangeType.InRange => comparisonResult <= 0 && comparisonResult2 <= 0,
                    RangeType.OutRange => comparisonResult > 0 || comparisonResult2 > 0,
                    _ => throw new InvalidOperationException("Unsupported comparison type."),
                };
            }
            else
            {
                return false;
            }

        }
    }
}
